Security News
RubyGems.org Adds New Maintainer Role
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
A fast prototype based Javascript Class implementation
Desktop Browsers:
Mobile Browsers:
using npm
npm i ee-class
using bower
bower i ee-class
node
let Class = require('ee-class');
require.js
you have to configure require.js to point the bower prefix to the bower_components folder. this is optional, but if you are using any other components of this author they will depend on this config for requiring other dependencies.
requirejs.config({
paths: {
'bower': '/js/bower_components/'
}
});
and finally load the component
require(['bower/ee-class/dist/ee-class.min'], function(Class) {
});
Browser & Vanilla
<script src="bower/ee-class/dist/ee-class.min" />
var Class = window.ee.Class;
The Class implementation is built on top of javascript prototype based inheritance and ECMA Script property descriptors.
Classes can be created using the Class function. The function expects exactly one argument, the class definition.
var MyClass = new Class();
Objects & Functions on this property are handled as the prototype for the prototype of the class you are creating.
var MyClass = new Class({
inherits: Array
});
// { // MyClass instance
// __proto__: { // MyClass protoype (where your items from the classdefinition are placed)
// __proto__: { // the Array prototype
// __proto__: {} // the prototype of the array prototype («[Object object]»)
// }
// }
// }
Functions will be placed on the Classes prototype object, they are by default not configurable, not writeable and enumerable (except for properties starting with an «_». If the property has the name «init» it is treated as the classes constructor.
var MyClass = new Class({
init: function(){
console.log('im executed when the class is instantiated');
}
});
var instance = new MyClass(); // im executed when the class is instantiated
console.dir(instance); // {} -> the init function is placed on the instances
// prototype
console.log(intance.init); // { [Function: init] super: [Function] }
console.log(instance instanceof MyClass); // true
console.log(instance instanceof Object); // true
console.log(instance instanceof Date); // false
Note the super property on the init function, it can be used to call the constructor of the next constructor function in the prototype chain.
The Class definition may contain property descriptor objects. You are able to create configure each of the properties exactly as you like. You can create getters and setters and configure the configurability, the writability and the enumerability.
var Person = new Class({
init: function(options){
if (options && options.name !== undefined) this.name = options.name;
if (options && options.age !== undefined) this.age = options.age;
}
// the private storage for the age value
, _storage: {
value: {
age: null
}
}
, name: '' // enumerable, writable, not configurable
, age: {
get: function(){ return this._storage.age; }
, set: function(value) {
if (value < 0) throw new Error('Please provide an age >= 0!');
else if (value > 150) throw new Error('You are too old, sorry!');
else this._storage.age = value;
}
, enumerable: true
/* , configurable: false */ // defaults to false
/* , writable: false */ // defaults to false
}
, sayHelloTo: {
value: function(name){
console.log('Hello %s, my name is %s and im %s years old :)'
, name, this.name, this.age);
}
}
});
var instance = new Person({name: 'Michael', age: 30});
instance.sayHelloTo('Tobias'); // Hello Tobias, my name is Michael and im 30
// years old :)
// Object keys hets all enumerable keys from the instance but not its
// prototypes
console.log(Object.keys(instance)); // [ 'name' ]
// Class.keys() gets all enumerable keys from the instance and all its
// prototypes
// Class.keys -> for (var key in instance) keys.push(key);
console.log(Class.keys(instance)); // [ 'name', 'init', 'age' ]
// internal structure of the Person instance
{
name: 'Michael' // this was set from inside the constructor function
, __proto__: { // the Person prototype
init: function(){ ... }
, _storage: {
age: 30 // set by the constructor, ATTENTION: this is shared
// across all «Person» instances
}
, name: '' // deafult wont be changed anytime
, age: [Getter / Setter]
, sayHelloTo: function(){ ... }
, __proto__: {} // default prototype
}
}
The example above has one problem. All instances of the «Person» class are going to share the «_storage» property. This is because it's a property which will not be set on the instance itself but only once on the prototype. A Better solution would be the follwoing:
var Person = new Class({
init: function(options){
Object.defineProperty(this, '_storage', {value: {}});
Class.define(this, '_storage', {value: {}}); // alternative syntax
Class.define(this, '_storage', Class({})) // alternatove syntax
....
}
...
});
Any class may inherit from any oter class or builtin types.
var LifeForm = new Class({
init: function(isAlive) {
Class.define(this, 'isAlive', Class(isAlive).Enumerable().Writable());
}
, isAlive: Class(false).Enumerable().Writable()
, die: function(){}
});
var Person = new Class({
inherits: LifeForm
, talk: function(){
console.log('Hi my name is %s, i\'m '+(this.isAlive ? 'alive :)'
: 'dead :('), this.name);
}
, sing: function() {}
});
var Boy = new Class({
inherits: Person
, init: function constructor(name, alive) {
// you need to give the function a name in order to be able to call
// its super. you must «call» or «apply» the super function to give
// it the correct context
constructor.super.call(this, alive);
this.name = Class.define(this, 'name', Class(name).Enumerable());
}
, run: function(){}
, jump: function(){}
});
var dylan = new Boy('Dylan', true);
dylan.talk(); // Hi my name is Dylan, i'm alive :)
// internal structure of the «dylan» Boy instanc
{
isAlive: true // defined by the LifeForm Class constructor
, name: 'Dylan' // defined by the Boy constructor
, __proto__: { // Boy prototype
init: function init(){ ... }
, __proto__: { // Person prototype
__proto__: { // LifeForm prototype
isAlive: false // property defined on the LifeForm class
, init: function(){ ... }
, __proto__: {} // defualt object prototype
}
}
}
}
console.log(dylan instanceof Boy); // true
console.log(dylan instanceof Person); // true
console.log(dylan instanceof LifeForm); // true
console.log(dylan instanceof Object); // true
console.log(dylan instanceof Array); // false
If a class inherits from another class and the top class overwrites a method of the inherited class and you need to access the method in the inherited class from within a method on the inherited class you can now do this via the function.local variable.
var BaseClass = new Class({
sayHi: function() {
console.log('base!');
}
, doSayHi: function doSayHi(localVersion) {
if (localVersion) doSayHi.local.sayHi();
else this.sayHi();
}
});
var TopClass = new Class({
inherits: BaseClass
, sayHi: function() {
console.log('top!');
}
});
var instance = new TopClass();
instance.sayHi(0); // top!
instance.sayHi(1); // base!
if the Class constructor is called without the new Keyword it doesnt create an instance of the class, it does instead return a class property definition which can be used by the Class.define or Object.defineProperty method.
Class(234) // {value: 234}
Class(true).enumerable() // {value: true, enumerable: true}
Class('yeah').writable() // {value: 'yeah', writable: true}
Class(new Error('nope')).configurable() // {value: Error, configurable: true}
Class(234).enumerable().writable().configurable() // {value: 234, enumerable: true, writable: true, configurable: true}
This can be used oin playe of the Object.defineProperty method.
Class.define({}, 'property_name', {value:3});
Returns the prototype of a class instance
var prototype = Class.proto(instance);
Returns all enumerable properties of a class instance and of all its prototypes. Object.keys does the same for only the class instance.
var keys = Class.keys(instance);
Implements methods and properties from a classinstance on another object.
var myObject = {};
var MyClass = new Class({
test: function(){
}
});
Class.implement(new MyClass(), myObject);
console.log(myObject); // {test: function(){}}
Inspects the internal structure of the class, returns it. Is helpful for debugging.
// inspecting the class instance created in the inheritnace example above
var description = Class.inspect(dylan);
log(description);
// { isAlive: true,
// name: 'Dylan',
// super:
// { init: [Function],
// jump: [Function],
// run: [Function],
// super:
// { sing: [Function],
// talk: [Function],
// super:
// { die: [Function],
// init: [Function],
// isAlive: false,
// super:
// { super:
// { __defineGetter__: [Function],
// __defineSetter__: [Function],
// __lookupGetter__: [Function],
// __lookupSetter__: [Function],
// constructor: [Function],
// hasOwnProperty: [Function],
// isPrototypeOf: [Function],
// propertyIsEnumerable: [Function],
// toLocaleString: [Function],
// toString: [Function],
// valueOf: [Function] } } } } } }
FAQs
Fast prototype based javascript classes
We found that ee-class demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.
Security News
Research
Socket's threat research team has detected five malicious npm packages targeting Roblox developers, deploying malware to steal credentials and personal data.